package com.cdu.supermarket.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.cdu.supermarket.common.exception.BusinessException;
import com.cdu.supermarket.common.redis.constants.RedisKeys;
import com.cdu.supermarket.common.redis.service.RedisTemplateService;
import com.cdu.supermarket.entity.domain.*;
import com.cdu.supermarket.entity.query.*;
import com.cdu.supermarket.entity.vo.*;
import com.cdu.supermarket.mapper.GoodsAttributeOptionMapper;
import com.cdu.supermarket.mapper.GoodsMapper;
import com.cdu.supermarket.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {

    @Resource
    private RedisTemplateService redisTemplateService;

    @Resource
    private IGoodsCategoryService goodsCategoryService;

    @Resource
    private IStoreService storeService;

    @Resource
    private IDetailStoreGoodsService detailStoreGoodsService;

    @Resource
    private IGoodsStoreService goodsStoreService;

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private IGoodsAttributeValueService attributeValueService;
    @Resource
    private IGoodsAttributeService attributeService;

    @Resource
    private GoodsAttributeOptionMapper attributeOptionMapper;

    @Override
    public Page<GoodsListVo> queryPageByQo(QueryGoods qo) {
        Page<GoodsListVo> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        ArrayList<GoodsListVo> volists = new ArrayList<>();
        Page<Goods> goodsPage = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        QueryWrapper<Goods> wrapper = new QueryWrapper<Goods>()
                .eq(qo.getId() != null, "id", qo.getId())
                .eq(qo.getSellPrice() != null, "sell_price", qo.getSellPrice())
                .like(StringUtils.hasText(qo.getName()), "name", qo.getName())
                .eq(qo.getCategoryId() != null, "category_id", qo.getCategoryId())
                .eq(StringUtils.hasText(qo.getState()), "state", qo.getState())
                .ge(StringUtils.hasText(qo.getOperateStartTime()), "update_time", qo.getOperateStartTime())
                .le(StringUtils.hasText(qo.getOperateEndTime()), "update_time", qo.getOperateEndTime());
        super.page(goodsPage, wrapper);
        for (Goods record : goodsPage.getRecords()) {
            GoodsListVo vo = new GoodsListVo();
            BeanUtils.copyProperties(record, vo);
            Long residueNum=storeService.getResidueNumByGoodsId(record.getId());
            vo.setResidueStoreNum(residueNum);
            volists.add(vo);
        }
        page.setRecords(volists);
        page.setTotal(goodsPage.getTotal());
        return page;
    }

    @Override
    public void saveGoods(Goods goods, String token) {
        Employee employee = JSONObject.parseObject(redisTemplateService.getCacheObject(token), Employee.class);
        goods.setState(Goods.STATE_UP);
        goods.setCreateby(employee.getNickName());
        goods.setUpdateby(employee.getNickName());
        goods.setCreateTime(new Date());
        goods.setUpdateTime(new Date());
        if (goods.getCategoryId() != null) {
            /*从缓存中获取分类的信息*/
            if (redisTemplateService.hasKey(RedisKeys.GOODS_CATEGORY.join())) {
                Map<String, Object> categoryCache = redisTemplateService.getCacheMap(RedisKeys.GOODS_CATEGORY.join());
                GoodsCategory category = (GoodsCategory) categoryCache.get(goods.getCategoryId().toString());
                if (category != null) {
                    goods.setCategoryName(category.getName());
                }
            } else {
                GoodsCategory category = goodsCategoryService.getById(goods.getCategoryId());
                if (category != null) {
                    goods.setCategoryName(category.getName());
                }
            }
        }
        super.save(goods);
    }

    @Transactional
    @Override
    public void upOrdown(Long gid, String state,String token) {
        UpdateWrapper<Goods> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", gid);
        if (Goods.STATE_UP.equals(state)) {
            Employee employee = JSONObject.parseObject(redisTemplateService.getCacheObject(token), Employee.class);
            wrapper.set("state", Goods.STATE_DOWN);
            Goods goods = super.getById(gid);
            QueryWrapper<GoodsStore> goodsStoreQueryWrapper = new QueryWrapper<GoodsStore>().eq("goods_id", gid);
            List<GoodsStore> list = goodsStoreService.list(goodsStoreQueryWrapper);
            for (GoodsStore goodsStore : list) {
                DetailStoreGoods detailStoreGoods = new DetailStoreGoods();
                detailStoreGoods.setCreateid(employee.getId());
                detailStoreGoods.setCreateby(employee.getNickName());
                detailStoreGoods.setCreateTime(new Date());
                detailStoreGoods.setGoodsId(gid);
                detailStoreGoods.setGoodsName(goods.getName());
                detailStoreGoods.setType(DetailStoreGoods.TYPE_IN);
                detailStoreGoods.setState1(DetailStoreGoods.STATE1_UNTREATED);
                detailStoreGoods.setState(DetailStoreGoods.STATE_DOWN);
                detailStoreGoods.setCn(IdWorker.getIdStr());
                detailStoreGoods.setInfo(goods.getName()+"下架处理");
                detailStoreGoods.setGoodsNum(goodsStore.getResidueNum());
                detailStoreGoods.setUntreatedNum(goodsStore.getResidueNum());
                detailStoreGoods.setStoreId(goodsStore.getStoreId());
                detailStoreGoodsService.save(detailStoreGoods);
            }
        } else {
            wrapper.set("residue_num",0);
            wrapper.set("state", Goods.STATE_UP);
            QueryWrapper<DetailStoreGoods> queryWrapper = new QueryWrapper<DetailStoreGoods>().eq("goods_id", gid)
                    .eq("state", DetailStoreGoods.STATE_DOWN)
                    .eq("state1", DetailStoreGoods.STATE1_UNTREATED);
            detailStoreGoodsService.remove(queryWrapper);
        }
        super.update(wrapper);

    }

    @Override
    public void updateGoods(Goods goods, String token) {
        Employee employee = JSONObject.parseObject(redisTemplateService.getCacheObject(token), Employee.class);
        goods.setUpdateby(employee.getNickName());
        goods.setUpdateTime(new Date());
        if (goods.getCategoryId() != null) {
            /*从缓存中获取分类的信息*/
            if (redisTemplateService.hasKey(RedisKeys.GOODS_CATEGORY.join())) {
                Map<String, Object> categoryCache = redisTemplateService.getCacheMap(RedisKeys.GOODS_CATEGORY.join());
                GoodsCategory category = (GoodsCategory) categoryCache.get(goods.getCategoryId().toString());
                if (category != null) {
                    goods.setCategoryName(category.getName());
                }
            } else {
                GoodsCategory category = goodsCategoryService.getById(goods.getCategoryId());
                if (category != null) {
                    goods.setCategoryName(category.getName());
                }
            }
        }
        super.updateById(goods);
    }

    @Override
    public List<Map<String, Object>> selected_goodsAll() {
        QueryWrapper<Goods> wrapper = new QueryWrapper<Goods>().eq("state", Goods.STATE_UP);
        List<Goods> list = super.list(wrapper);
        if (list==null&&list.size()==0){
            return null;
        }
        List<Map<String, Object>> listVo = new ArrayList<>();
        for (Goods goods : list) {
            Map<String, Object> map = new HashMap<>();
            map.put("id",goods.getId());
            map.put("name",goods.getName());
            listVo.add(map);
        }

        return listVo;
    }

    @Override
    public List<Map<String, Object>> selected_storeAll() {
        List<Map<String, Object>> list = new ArrayList<>();
        QueryWrapper<Store> wrapper = new QueryWrapper<Store>().eq("state", Store.STATE_NORMAL);
        List<Store> list1 = storeService.list(wrapper);
        if (list1!=null &&list1.size()>0){
            for (Store store : list1) {
                Map<String, Object> map = new HashMap<>();
                map.put("id",store.getId());
                map.put("name",store.getName());
                list.add(map);
            }
        }
        return list;
    }

    @Override
    public void returnGoods(DetailStoreGoods detailStoreGoods, String token) {
        Employee employee = JSONObject.parseObject(redisTemplateService.getCacheObject(token), Employee.class);
        Goods goods = super.getById(detailStoreGoods.getGoodsId());

        /*补全入库订单信息*/
        detailStoreGoods.setCn(IdWorker.getIdStr());
        detailStoreGoods.setCreateby(employee.getNickName());
        detailStoreGoods.setCreateid(employee.getId());
        detailStoreGoods.setType(DetailStoreGoods.TYPE_IN);
        if (DetailStoreGoods.STATE_EXPIRY.equals(detailStoreGoods.getState())){
            //如果是过期，将入库订单的state1修改成2：待处理的状态
            detailStoreGoods.setState1(DetailStoreGoods.STATE1_UNTREATED);
        }else {
            detailStoreGoods.setState1(DetailStoreGoods.STATE1_NORMAL);
        }


        /*获取仓库的信息*/
        QueryWrapper<GoodsStore> goodsStoreQueryWrapper = new QueryWrapper<GoodsStore>()
                .eq("goods_id", detailStoreGoods.getGoodsId())
                .eq("store_id", detailStoreGoods.getStoreId());
        GoodsStore goodsStore = goodsStoreService.getOne(goodsStoreQueryWrapper);
        if (goodsStore==null){
            goodsStore = new GoodsStore();
            goodsStore.setGoodsId(detailStoreGoods.getGoodsId());
            goodsStore.setStoreId(detailStoreGoods.getStoreId());
            Store store = storeService.getById(detailStoreGoods.getStoreId());
            goodsStore.setStoreName(store.getName());
            goodsStore.setInNum(0L);
            goodsStore.setResidueNum(0L);
            goodsStoreService.save(goodsStore);
        }
        long num = goods.getResidueNum() - detailStoreGoods.getGoodsNum();
        if (num>=0){
            //货架还有商品数量
            /*更改商品信息*/
            UpdateWrapper<Goods> goodsUpdateWrapper = new UpdateWrapper<Goods>()
                    .set("residue_num", num)
                    .eq("id", detailStoreGoods.getGoodsId());
            super.update(goodsUpdateWrapper);
            /*更改商品库存信息*/
            UpdateWrapper<GoodsStore> goodsStoreUpdateWrapper = new UpdateWrapper<GoodsStore>()
                    .set("residue_num", goodsStore.getResidueNum() + detailStoreGoods.getGoodsNum())
                    .eq("goods_id", detailStoreGoods.getGoodsId())
                    .eq("store_id", detailStoreGoods.getStoreId());
            goodsStoreService.update(goodsStoreUpdateWrapper);
            detailStoreGoods.setUntreatedNum(detailStoreGoods.getGoodsNum());

        }else {
            //货架没有商品数量
            /*更改商品信息*/
            UpdateWrapper<Goods> goodsUpdateWrapper = new UpdateWrapper<Goods>()
                    .set("residue_num", 0)
                    .eq("id", detailStoreGoods.getGoodsId());
            super.update(goodsUpdateWrapper);
            /*更改商品库存信息*/
            UpdateWrapper<GoodsStore> goodsStoreUpdateWrapper = new UpdateWrapper<GoodsStore>()
                    .set("residue_num", goodsStore.getResidueNum() + goods.getResidueNum())
                    .eq("goods_id", detailStoreGoods.getGoodsId())
                    .eq("store_id", detailStoreGoods.getStoreId());
            goodsStoreService.update(goodsStoreUpdateWrapper);
            detailStoreGoods.setGoodsNum(goods.getResidueNum());
            detailStoreGoods.setUntreatedNum(goods.getResidueNum());
        }
        detailStoreGoodsService.save(detailStoreGoods);
    }

    @Override
    public Page<GoodsStoreVo> queryPageGoodsStore(QueryGoodsStore qo) {
        Page<GoodsStoreVo> page = new Page<>(qo.getCurrentPage(),qo.getPageSize());
        Page<Goods> goodsPage = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        QueryWrapper<Goods> wrapper = new QueryWrapper<Goods>().eq("state", Goods.STATE_UP)
                .like(StringUtils.hasText(qo.getName()), "name", qo.getName());
        super.page(goodsPage,wrapper);
        if (goodsPage.getTotal()<=0) {
            page.setRecords(new ArrayList<>());
            page.setTotal(0);
            return page;
        }
        List<GoodsStoreVo> list = new ArrayList<>();
        for (Goods record : goodsPage.getRecords()) {
            GoodsStoreVo vo = new GoodsStoreVo();
            BeanUtils.copyProperties(record,vo);
            list.add(vo);
        }
        page.setTotal(goodsPage.getTotal());
        page.setRecords(list);
        return page;
    }

    @Override
    public GoodsStoreVo queryGoodsStoreById(Long id) {
        GoodsStoreVo vo = new GoodsStoreVo();
        Goods goods = super.getById(id);
        BeanUtils.copyProperties(goods,vo);
        return vo;
    }

    @Override
    public void updateInventory(GoodsStoreVo vo) {
        if (vo.getInventory()==null){
            vo.setInventory(0L);
        }
        if(vo.getShelves()==null){
            vo.setShelves(0L);
        }
        UpdateWrapper<Goods> updateWrapper = new UpdateWrapper<Goods>()
                .set("inventory",vo.getInventory())
                .set("shelves",vo.getShelves())
                .eq("id",vo.getId());
        super.update(updateWrapper);

    }

    @Override
    public SalesStatisticsVo queryPageStatisticSaleByQo(QueryStatisticSale qo) {
       Long total=goodsMapper.queryPageStatisticSaleByQo(qo.getName());
        SalesStatisticsVo vo = new SalesStatisticsVo();
        vo.setTotal(total);
        QueryWrapper<Goods> wrapper = new QueryWrapper<Goods>().eq("state", Goods.STATE_UP)
                .like(StringUtils.hasText(qo.getName()), "name", qo.getName());
        Page<Goods> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        super.page(page,wrapper);
        Page<SaleGoodsVo> saleGoodsVoPage = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        saleGoodsVoPage.setTotal(page.getTotal());
        List<SaleGoodsVo> saleGoodsVos = new ArrayList<>();
        for (Goods record : page.getRecords()) {
            SaleGoodsVo goodsVo = new SaleGoodsVo();
            goodsVo.setGoodsId(record.getId());
            goodsVo.setGoodsName(record.getName());
            goodsVo.setSalesVolume(record.getSalesVolume());
            goodsVo.setPercentage(total);
            goodsVo.setCoverUrl(record.getCoverUrl());
            saleGoodsVos.add(goodsVo);
        }
        saleGoodsVoPage.setRecords(saleGoodsVos);
        vo.setVos(saleGoodsVoPage);
        return vo;
    }


    @Override
    @Transactional(readOnly = true)
    public Goods getGoodsWithAttributes(Long id) {
        Goods goods = super.getById(id);
        if (goods == null) {
            return null;
        }

        // 新建商品属性值
        List<GoodsAttributeValue> attributes = new ArrayList<>();
        // 查询商品未设置属性
        List<GoodsAttribute> goodsAttributes= attributeService.listByCategoryId(goods.getCategoryId());

        for (GoodsAttribute goodsAttribute : goodsAttributes) {
            GoodsAttributeValue attribute = attributeValueService.lambdaQuery().eq(GoodsAttributeValue::getAttrId, goodsAttribute.getId())
                    .eq(GoodsAttributeValue::getGoodsId, id).one();
            if(attribute==null){
                attribute=new GoodsAttributeValue();
                attribute.setGoodsId(id);
                attribute.setAttrId(goodsAttribute.getId());
                attribute.setOptions(goodsAttribute.getOptions());
            }
            attribute.setAttrName(goodsAttribute.getName());
            attribute.setAttrCode(goodsAttribute.getCode());
            attribute.setAttrType(goodsAttribute.getAttrType());
            attributes.add( attribute);
        }
        // 处理enum类型属性，获取选项列表
        if (attributes != null && !attributes.isEmpty()) {
            for (GoodsAttributeValue attr : attributes) {
                if ("enum".equals(attr.getAttrType())) {
                    // 查询该属性的所有选项
                    QueryWrapper<GoodsAttributeOption> optionWrapper = new QueryWrapper<>();
                    optionWrapper.eq("attr_id", attr.getAttrId())
                               .orderByAsc("sort_order");
                    List<GoodsAttributeOption> options = attributeOptionMapper.selectList(optionWrapper);
                    attr.setOptions(options);
                    
                    // 添加日志，帮助调试
                    System.out.println("属性ID: " + attr.getAttrId() + ", 名称: " + attr.getAttrName() + 
                                      ", 选项数量: " + (options != null ? options.size() : 0));
                    if (options != null && !options.isEmpty()) {
                        for (GoodsAttributeOption option : options) {
                            System.out.println("  - 选项: " + option.getOptionValue());
                        }
                    }
                }
            }
        }
        
        goods.setAttributes(attributes);
        
        // 构建属性Map方便使用
        Map<String, Object> attrMap = new HashMap<>();
        if (attributes != null) {
            for (GoodsAttributeValue attr : attributes) {
                // 根据属性类型进行转换
                if ("number".equals(attr.getAttrType())) {
                    try {
                        attrMap.put(attr.getAttrCode(), Double.parseDouble(attr.getValue()));
                    } catch (NumberFormatException e) {
                        attrMap.put(attr.getAttrCode(), attr.getValue());
                    }
                } else if ("boolean".equals(attr.getAttrType())) {
                    attrMap.put(attr.getAttrCode(), "1".equals(attr.getValue()) 
                        || "true".equalsIgnoreCase(attr.getValue()));
                } else {
                    attrMap.put(attr.getAttrCode(), attr.getValue());
                }
            }
        }
        goods.setAttributeMap(attrMap);
        
        return goods;
    }
    
    @Override
    @Transactional
    public boolean saveGoodsWithAttributes(Goods goods) {
        boolean result = super.save(goods);
        
        // 保存商品属性值
        if (result && goods.getAttributes() != null && !goods.getAttributes().isEmpty()) {
            for (GoodsAttributeValue attribute : goods.getAttributes()) {
                attribute.setGoodsId(goods.getId());
                attributeValueService.save(attribute);
            }
        }
        
        return result;
    }
    
    @Override
    @Transactional
    public boolean updateGoodsWithAttributes(Goods goods) {
        boolean result = super.updateById(goods);
        
        if (result) {
            // 删除原有属性值
            attributeValueService.removeByGoodsId(goods.getId());
            
            // 保存新属性值
            if (goods.getAttributes() != null && !goods.getAttributes().isEmpty()) {
                for (GoodsAttributeValue attribute : goods.getAttributes()) {
                    attribute.setGoodsId(goods.getId());
                    attributeValueService.save(attribute);
                }
            }
        }
        
        return result;
    }

    @Override
    @Transactional
    public void updateGoodsAttributes(Goods goods, String token) {
        Employee employee = JSONObject.parseObject(redisTemplateService.getCacheObject(token), Employee.class);
        
        // 更新商品基本信息的修改时间和操作者
        UpdateWrapper<Goods> goodsUpdateWrapper = new UpdateWrapper<>();
        goodsUpdateWrapper.eq("id", goods.getId())
                         .set("update_time", new Date())
                         .set("updateby", employee.getNickName());
        super.update(goodsUpdateWrapper);
        
        // 获取现有属性信息，确保保留其他字段
        List<GoodsAttributeValue> existingAttributes = attributeValueService.listByGoodsId(goods.getId());
        Map<Long, GoodsAttributeValue> existingAttributesMap = new HashMap<>();
        if (existingAttributes != null && !existingAttributes.isEmpty()) {
            for (GoodsAttributeValue attr : existingAttributes) {
                existingAttributesMap.put(attr.getId(), attr);
            }
        }
        
        // 更新属性值
        if (goods.getAttributes() != null && !goods.getAttributes().isEmpty()) {
            for (GoodsAttributeValue attribute : goods.getAttributes()) {
                // 确保设置商品ID
                attribute.setGoodsId(goods.getId());
                
                // 检查属性是否存在
                if (attribute.getId() != null) {
                    // 获取现有属性的完整信息
                    GoodsAttributeValue existingAttr = existingAttributesMap.get(attribute.getId());
                    if (existingAttr != null) {
                        // 对于枚举类型，验证值是否在选项中
                        if ("enum".equals(existingAttr.getAttrType()) || "enum".equals(attribute.getAttrType())) {
                            // 查询该属性的所有选项
                            QueryWrapper<GoodsAttributeOption> optionWrapper = new QueryWrapper<>();
                            optionWrapper.eq("attr_id", existingAttr.getAttrId())
                                       .orderByAsc("sort_order");
                            List<GoodsAttributeOption> options = attributeOptionMapper.selectList(optionWrapper);
                            
                            // 验证值是否在选项列表中
                            boolean isValidValue = false;
                            for (GoodsAttributeOption option : options) {
                                if (option.getOptionValue().equals(attribute.getValue())) {
                                    isValidValue = true;
                                    break;
                                }
                            }
                            
                            // 如果值无效，使用第一个选项值或保留原值
                            if (!isValidValue && !options.isEmpty()) {
                                attribute.setValue(options.get(0).getOptionValue());
                            }
                        }
                        
                        // 使用更新而不是替换，避免覆盖其他字段
                        UpdateWrapper<GoodsAttributeValue> updateWrapper = new UpdateWrapper<>();
                        updateWrapper.eq("id", attribute.getId())
                                    .set("value", attribute.getValue());
                        attributeValueService.update(updateWrapper);
                    }
                } else {
                    // 如果是新属性，需要验证并补充完整信息
                    // 这里需要根据attrId查询属性定义信息
                    attributeValueService.save(attribute);
                }
            }
        }
    }

}
